<?php
namespace classlib\acl;
use \classlib\core\model;
abstract class acl_abstract {
	/**
	 * 存放账号解密数据提取
	 * @var array or null
	 */
	public $user = null;
	
	/**
	 * 定义系统别-验证是给多系统使用
	 * 不同ckey要自定一个唯一的id
	 * @var int
	 */
	public $sys  = 0;
		
	/**
	 * 定义系统的cookie key值资料
	 * 如果同一个域名有两套KEY的话需要自行定义
	 * @var string
	 */
	public $ckey = 'sid';
	
	/**
	 * 定义临时密码的保存ORM
	 * @var string
	 */
	public $model= 'main.sys.safe';
	
	/**
	 * 构造实例化一个Acl
	 * @param array $args
	 */
	public function __construct($args) {
		isset($args['sys']) && ($this->sys     = $args['sys']);
		isset($args['ckey']) && ($this->ckey   = $args['ckey']);
		isset($args['model']) && ($this->model = $args['model']);
	}
	
	/**
	 * 设置指定账号ID的密码资料信息主要是记录到cache
	 * @param int $id
	 * @param string $loginpw
	 * @param int $expire
	 * @return $loginpw
	 */
	public function ss($id, $loginpw, $expire=0) {
		$orm   = model::load($this->model)->get_orm();
		$table = model::load($this->model)->set_mod($id)->get_table();
		$tocken= mt_rand(1000, 9999);
		$orm->clear()->table($table)->duplicate(array('tocken'=>$tocken, 'loginpw'=>$loginpw, 'expire'=>$expire))
			->insert(array('userid'=>$id, 'sys'=>$this->sys, 'loginpw'=>$loginpw, 'tocken'=>$tocken, 'expire'=>$expire));
		//设置缓存信息
		$loginpw = sprintf('%s-%s', $tocken, $loginpw);
		if ($expire > 1) {
			$expire = $expire - time();
		}
		$skey = self::skey($id, $this->ckey, $this->sys);
		model::$cacher->set($skey, $loginpw, $expire);
		return $loginpw;
	}
	
	/**
	 * 获取自定ID的密钥，用作签名校验
	 * @param int $id
	 */
	public function gs($id) {
		$skey    = self::skey($id, $this->ckey, $this->sys);
		$loginpw = model::$cacher->get($skey);
		if (!$loginpw) {
			$safe= model::load($this->model)->set_mod($id)->get_orm()
				->where('userid', $id)->where('sys', $this->sys)->get_row();
			if ($safe && ($safe['expire'] == 0 || $safe['expire'] > time())) {
				$loginpw = sprintf('%s-%s', $safe['tocken'], $safe['loginpw']);
				$expire  = ($safe['expire'] < 1)? 0:($safe['expire'] - time());
				model::$cacher->set($skey, $loginpw, $expire);
			}
		}
		return $loginpw;
	}
	
	/**
	 * 程序页面验证是否登录
	 * @param  string $sign 验证的签名资料信息
	 * @return boolean
	 */
	abstract public function islogin($sign='');
	
	/**
	 * 设置一个账号为登录状态
	 * @param array $user
	 * @param string $loginpw
	 * @param int   $expire
	 * @param bool  $cookie
	 * 
	 * @return string
	 */
	abstract public function signin($user, $loginpw, $expire=0, $cookie=true);
	
	/**
	 * 注销登录的资料信息
	 * @return boolean
	 */
	abstract public function signout();
	
	/**
	 * 登陆密码加密
	 * @param string $loginpw
	 * @return string
	 */
	public function crypt($loginpw) {
		$seed = '@#$%^A()*%#@!!)(_+=';
		return md5($seed.$loginpw.$seed);
	}
	
	/**
	 * 登录密码校验机制
	 * @param string $plain
	 * @param string $loginpw
	 * @return boolean
	 */
	public function check($plain, $loginpw) {
		return (strcasecmp($loginpw, $this->crypt($plain)) == 0)? true:false;
	}
	
	/**
	 * 返回会员的Tocken的缓存Key信息
	 * @param int    $userid
	 * @param string $ckey
	 * @param int    $sys
	 * @return string
	 */
	public static function skey($userid, $ckey, $sys) {
		return sprintf('safe@%s-%d-%d', $ckey, $sys, $userid);
	}
}